#include "bsp_adc.h"
#include "bsp_i2c.h"
#include "i2c_oled.h"


// 是与电阻相连的adc外设及其channel的初始化
void adc_init(void){
	adc_gpio_config();
	adc_config();
}

/* 初始化IO口为模拟输入模式 */
void adc_gpio_config(){
	rcu_periph_clock_enable(RCU_GPIOA);  //1.使能rcu时钟
    gpio_init(GPIOA, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, GPIO_PIN_4 |GPIO_PIN_5);  //2.初始化gpio模式
}

/* 初始化adc0 */
void adc_config(){
	rcu_periph_clock_enable(RCU_ADC0);            // 使能时钟
	rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);  // 配置ADC的时钟
	
	/* 配置ADC0的参数 */
	adc_mode_config(ADC_MODE_FREE);                                  // 自由模式
	adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);        
	adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE); //关闭连续模式
	
	adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);      //对齐方式
	adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);
	
	adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_2_EXTTRIG_REGULAR_NONE); // 触发方式,软件触发
	adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);  // 使能外部触发
	
	/* 使能ADC0 */
	adc_enable(ADC0);
	delay_1ms(2);     //等待稳定
	
	/* 自校准 */
	adc_calibration_enable(ADC0);
}

// 读取ADC0转换的结果
uint16_t read_adc0_data(uint8_t adc_channel){
	/*配置adc0的通道*/
	adc_regular_channel_config(ADC0, 0, adc_channel, ADC_SAMPLETIME_1POINT5);
	
	/*触发adc0的转换*/
	adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
	
	/*等待EOC置位，即ADC0转换完成*/
	while(!adc_flag_get(ADC0, ADC_FLAG_EOC));
	/*清零EOC*/
	adc_flag_clear(ADC0, ADC_FLAG_EOC);
	
	/*读常规通道数据寄存器值并返回*/
	return adc_regular_data_read(ADC0);
}

/*获取光敏电阻的阻值, 
* return:光敏电阻阻值，单位是千欧
*/
float get_photo_r(void){
	uint16_t adc_value = 0;
	uint8_t i;
	for(i=0; i<8; i++){
    	adc_value += read_adc0_data(ADC_CHANNEL_5);
	}
	
	adc_value = adc_value / 8;
	
	float v_photo_res = adc_value * 3.3f / 4096.0f;  //得到模数转换的结果对应的电压值
	float result = (v_photo_res * 10) / (3 - v_photo_res);
	return result; 
}

/*获取可调电阻的阻值, 
* return:可调电阻阻值，单位是千欧
*/
float get_var_r(void){      
	uint16_t adc_value = 0;
	uint8_t i;
	for(i=0; i<8; i++){
    	adc_value += read_adc0_data(ADC_CHANNEL_4);
	}
	
	adc_value = adc_value / 8;
	
	float v_var_res = adc_value * 3.3f / 4096.0f;  //得到模数转换的结果对应的电压值
	float result = (v_var_res * 10) / (3 - v_var_res);
	return result; 
}


void adc_test(void)
{
    bsp_i2c_init();
	
	oled_init();
	oled_clear_all();
	oled_set_char_size(kcharsize_6x8);
	oled_show_string(1, 1, "Resister ADC");
	
	adc_init();
	float photo_res;  //存放光敏电阻阻值
	float var_res;    //存放可调电阻阻值
	
	char temp_string[20];  // 存放数值转为字符串的结果

	while(1){
		// 显示光敏电阻转换的结果
		photo_res = get_photo_r();
		sprintf(temp_string, "photo_res:%.1fKohm", photo_res);

		oled_show_string(2, 1, (uint8_t *)temp_string);
		
		// 显示可调电阻转换的结果
		var_res = get_var_r();
		sprintf(temp_string, "var_res:%.1fKohm", var_res);
		oled_show_string(3, 1, (uint8_t *)temp_string);
		
	}
}